package com.gframework.samplecode;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;

class A{
	
}
class B implements MethodInterceptor {

	@Override
	public Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable {
//		var4.invoke(new A(), var3);	// 调用代理对象的方法，方法内调用本类方法不会再经过代理对象，因为this是非代理对象
//		var4.invokeSuper(new A(), var3);	// 会出错，因为A无法转换为A的子类（cglib代理类）
//		var4.invokeSuper(var1, var3);	// 让代理对象作为this去调用，并且调用则个方法的时候使用super.xxx的方式，这样一个是防止无限递归，一个是在方法内再去调用其他本类方法的时候，依然会经过代理方法
//		var4.invoke(var1, var3);	// 无限递归出错
		
		System.out.println("Hello World");
		return var2.invoke(new A(), var3);	// 等同于 var4.invoke(new A(), var3);
	}
	
}
public class CGLIBDemo {
	public static void main(String[] args) {

        //在指定目录下生成动态代理类，我们可以反编译看一下里面到底是一些什么东西
//        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\java\\java_workapace");
		
		Enhancer s = new Enhancer();
		s.setSuperclass(A.class);
		s.setCallbacks(new Callback[]{new B(),NoOp.INSTANCE});
		// 控制那个方法用那个callback。利用NoOp.INSTANCE，这样处理会比在方法内通过name 然后equals再去做逻辑判断要好得多。
		s.setCallbackFilter(new CallbackFilter(){
			@Override
			public int accept(Method m) {
				if (m.getName().equals("toString")) {
					return 0 ;
				} else {
					return 1;
				}
			}
			
		});
//		A a = (A) Enhancer.create(A.class, new B());
		A a = (A) s.create();
		System.out.println(a.toString());
//		System.out.println(a.hashCode());
	}
}
